package cn.mp.generator.util;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.mp.generator.MybatisPlusGeneratorApplication;
import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder;
import com.baomidou.mybatisplus.generator.config.po.TableField;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.*;

/**
 * @author zhuyuejun
 * @date 2021/4/26 11:57
 */
public class GennerCodeUtils {

    static String[] filterList = {"createdTime", "createdBy", "updatedTime", "updatedBy"};

    public static void gennerCodes(ConfigBuilder configBuilder) throws IOException {
        List<String> stringList = Arrays.asList(filterList);
        String entityDir = configBuilder.getPackageInfo().get("Entity").replace(".entity","");
        String replaceAll = entityDir.replaceAll("\\.", "/");
        String basepath = MybatisPlusGeneratorApplication.class.getResource("/").getPath();
        File baseFile = new File(basepath);
        if (!baseFile.exists()) {
            System.out.println(basepath + "目录不存在！");
            return;
        }
        String absolutePath = baseFile.getParentFile().getParentFile().getCanonicalPath();
        absolutePath = absolutePath + "/"+configBuilder.getGlobalConfig().getOutputDir()+"/" + replaceAll + "/";
        List<TableInfo> tableInfoList = configBuilder.getTableInfoList();
        List<String> poNames = new ArrayList<>();
        for (int i = 0; i < tableInfoList.size(); i++) {
            TableInfo tableInfo = tableInfoList.get(i);
            int length = tableInfo.getEntityName().length();
            String po = tableInfo.getEntityName().substring(0, length - 6);
            poNames.add(po);
        }
        List<GennerTemplate> list = new ArrayList<>();
        for (int i = 0; i < tableInfoList.size(); i++) {
            TableInfo tableInfo = tableInfoList.get(i);
            String po = poNames.get(i);
            try {
                GennerTemplate gennerTemplate = new GennerTemplate();
                gennerTemplate.setPoName(po);
                gennerTemplate.setComment(tableInfo.getComment());
                gennerTemplate.setEntityName(po);
                String substring = po.substring(0, 1).toLowerCase();
                String substring1 = po.substring(1);
                po = substring + substring1;
                gennerTemplate.setLowerEntityName(po);
                gennerTemplate.setPackageStr(entityDir);
                gennerTemplate.setFilds(tableInfo.getFields());
                Set<String> strings = new HashSet<>();
                for (TableField field : tableInfo.getFields()) {
                    if(StringUtils.isNotBlank(field.getColumnType().getPkg())){
                        strings.add(field.getColumnType().getPkg());
                    }
                }
                gennerTemplate.setImportPacks(strings);
                list.add(gennerTemplate);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        gennerVo(list, absolutePath);
        gennerDto(list, absolutePath);
        gennerQueryDto(list, absolutePath);
        gennerTransfer(list, absolutePath);
        gennerService(list, absolutePath);
        gennerServiceImpl(list, absolutePath);
        gennerController(list, absolutePath);
    }

    public static void gennerVo(List<GennerTemplate> gennerTemplates, String absolutePath) throws IOException {
        String voPath = absolutePath + "vo";
        File file3 = new File(voPath);
        if (!file3.exists()) {
            file3.mkdirs();
        }
        for (GennerTemplate gennerTemplate : gennerTemplates) {
            gennerTemplate.setPojoPath(voPath + "/" + gennerTemplate.getPoName() + "Vo.java");
            gennerTemplate.setType(1);
            createFile(gennerTemplate, "template/vo.java.vm");
        }
    }

    public static void gennerDto(List<GennerTemplate> gennerTemplates, String absolutePath) throws IOException {
        String dtoPath = absolutePath + "dto";
        File file2 = new File(dtoPath);
        if (!file2.exists()) {
            file2.mkdirs();
        }
        for (GennerTemplate gennerTemplate : gennerTemplates) {
            gennerTemplate.setPojoPath(dtoPath + "/" + gennerTemplate.getPoName() + "Dto.java");
            gennerTemplate.setType(2);
            createFile(gennerTemplate, "template/dto.java.vm");
        }
    }

    public static void gennerQueryDto(List<GennerTemplate> gennerTemplates, String absolutePath) throws IOException {
        String dtoPath = absolutePath + "dto";
        File file2 = new File(dtoPath);
        if (!file2.exists()) {
            file2.mkdirs();
        }
        for (GennerTemplate gennerTemplate : gennerTemplates) {
            gennerTemplate.setPojoPath(dtoPath + "/" + gennerTemplate.getPoName() + "PageQueryDto.java");
            gennerTemplate.setType(3);
            gennerTemplate.setSuperDto("BaseDto");
            createFile(gennerTemplate, "template/dto.java.vm");
        }
    }

    public static void gennerTransfer(List<GennerTemplate> gennerTemplates, String absolutePath) throws IOException {
        String transferPath = absolutePath + "transfer";
        File file4 = new File(transferPath);
        if (!file4.exists()) {
            file4.mkdirs();
        }
        for (GennerTemplate gennerTemplate : gennerTemplates) {
            gennerTemplate.setPojoPath(transferPath + "/" + gennerTemplate.getPoName() + "Transfer.java");
            gennerTemplate.setType(6);
            createFile(gennerTemplate, "template/transfer.java.vm");
        }
    }

    public static void gennerService(List<GennerTemplate> gennerTemplates, String absolutePath) throws IOException {
        String servicePath = absolutePath + "service";
        File file4 = new File(servicePath);
        if (!file4.exists()) {
            file4.mkdirs();
        }
        for (GennerTemplate gennerTemplate : gennerTemplates) {
            gennerTemplate.setPojoPath(servicePath + "/" + gennerTemplate.getPoName() + "Service.java");
            gennerTemplate.setType(4);
            createFile(gennerTemplate, "template/service.java.vm");
        }
    }

    public static void gennerServiceImpl(List<GennerTemplate> gennerTemplates, String absolutePath) throws IOException {
        String servicePath = absolutePath + "service/impl";
        File file4 = new File(servicePath);
        if (!file4.exists()) {
            file4.mkdirs();
        }
        for (GennerTemplate gennerTemplate : gennerTemplates) {
            gennerTemplate.setPojoPath(servicePath + "/" + gennerTemplate.getPoName() + "ServiceImpl.java");
            gennerTemplate.setType(5);
            createFile(gennerTemplate, "template/serviceimpl.java.vm");
        }
    }

    public static void gennerController(List<GennerTemplate> gennerTemplates, String absolutePath) throws IOException {
        String servicePath = absolutePath + "controller";
        File file4 = new File(servicePath);
        if (!file4.exists()) {
            file4.mkdirs();
        }
        for (GennerTemplate gennerTemplate : gennerTemplates) {
            gennerTemplate.setPojoPath(servicePath + "/" + gennerTemplate.getPoName() + "Controller.java");
            gennerTemplate.setType(7);
            createFile(gennerTemplate, "template/controller.java.vm");
        }
    }

    public static void createFile(GennerTemplate gennerTemplate, String templateFile) throws IOException {
        String path = MybatisPlusGeneratorApplication.class.getResource("/").getPath() + "/" + templateFile;

        String poName = gennerTemplate.getPoName();
        switch (gennerTemplate.getType()) {
            case 1:
                poName = poName + "Vo";
                break;
            case 2:
                poName = poName + "Dto";
                break;
            case 3:
                poName = poName + "PageQueryDto";
                break;
            case 4:
                poName = poName + "Service";
                break;
            case 5:
                poName = poName + "ServiceImpl";
                break;
            case 6:
                poName = poName + "Transfer";
                break;
            case 7:
                poName = poName + "Controller";
                break;
        }
        File file1 = FileUtil.newFile(path);
        FileInputStream fileInputStream = new FileInputStream(file1);
        String read = IoUtil.read(fileInputStream, "UTF-8");

        String replace = read.replace("${packageStr}", gennerTemplate.getPackageStr());
        replace = replace.replace("${poName}", poName + "");
        replace = replace.replace("${entityName}", gennerTemplate.getEntityName() + "");
        replace = replace.replace("${lowerEntityName}", gennerTemplate.getLowerEntityName() + "");
        replace = replace.replace("${comment}", gennerTemplate.getComment() + "");
        if (StringUtils.isBlank(gennerTemplate.getSuperDto())) {
            gennerTemplate.setSuperDto("");
        } else {
            gennerTemplate.setSuperDto("extends " + gennerTemplate.getSuperDto());
            gennerTemplate.getImportPacks().add("com.nos.framework.core.base.BaseDto");
        }
        replace = replace.replace("${superDto}", gennerTemplate.getSuperDto());
        StringBuffer ipostr = new StringBuffer("");
        for (String importS : gennerTemplate.getImportPacks()) {
            ipostr.append("\nimport " + importS + ";");
        }
        String replace1 = replace.replace("${importPacks}", ipostr);

        StringBuffer fildstr = new StringBuffer("");
        for (TableField tableField : gennerTemplate.getFilds()) {
            String comment = tableField.getComment();
            if(StringUtils.isBlank(comment)){
                comment =tableField.getPropertyName();
            }
            fildstr.append("\n\t@ApiModelProperty(\"" + comment + "\")\n\tprivate " + tableField.getColumnType().getType() + " " + tableField.getPropertyName() + ";");
        }

        String replace2 = replace1.replace("${filds}", fildstr);

        File file = FileUtil.newFile(gennerTemplate.getPojoPath());
        if (!file.exists()) {
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }
            file.createNewFile();
        }
        FileUtils.writeByteArrayToFile(file, replace2.getBytes());
    }
}
